// 前端基于 roles 控制菜单权限 - 通过登录后的用户角色对菜单进行过滤处理
// 如果需要使用前端 roles 控制菜单权限，请用此文件代码替换 permission.ts 的内容

import { defineStore } from 'pinia';
import { RouteRecordRaw } from 'vue-router';

import router, { allRoutes } from '@/router'; // 导入路由实例和全部路由配置
import { store } from '@/store'; // 导入基础store配置

/**
 * 根据用户角色过滤路由表
 * @param routes 原始路由表
 * @param roles 用户角色数组
 * @returns { accessedRouters: 可访问路由, removeRoutes: 需要移除的路由 }
 */
function filterPermissionsRouters(routes: Array<RouteRecordRaw>, roles: Array<unknown>) {
  const res: Array<RouteRecordRaw> = []; // 存储过滤后的可访问路由
  const removeRoutes: Array<RouteRecordRaw> = []; // 存储需要移除的路由

  // 遍历一级路由
  routes.forEach((route) => {
    const children: Array<RouteRecordRaw> = []; // 存储当前路由下可访问的子路由

    // 遍历子路由
    route.children?.forEach((childRouter) => {
      // 获取路由要求的角色代码（优先取meta.roleCode，没有则用路由name）
      const roleCode = childRouter.meta?.roleCode || childRouter.name;

      // 检查用户是否拥有该路由所需的角色
      if (roles.indexOf(roleCode) !== -1) {
        children.push(childRouter); // 有权限则加入可访问列表
      } else {
        removeRoutes.push(childRouter); // 无权限则加入移除列表
      }
    });

    // 如果当前路由有可访问的子路由，则保留该路由
    if (children.length > 0) {
      route.children = children; // 更新子路由为过滤后的列表
      res.push(route); // 加入可访问路由结果
    }
  });

  return { accessedRouters: res, removeRoutes };
}

// 定义权限store
export const usePermissionStore = defineStore('permission', {
  state: () => ({
    whiteListRouters: ['/login'], // 路由白名单（不需要权限校验的路由）
    routers: [], // 存储过滤后的可访问路由
    removeRoutes: [], // 存储需要移除的路由
  }),
  actions: {
    /**
     * 初始化路由（根据用户角色过滤路由）
     * @param roles 用户角色数组
     */
    async initRoutes(roles: Array<unknown>) {
      let accessedRouters = []; // 可访问路由
      let removeRoutes: Array<RouteRecordRaw> = []; // 需要移除的路由

      // 特殊权限检查 - 如果拥有'all'角色则拥有全部路由权限
      if (roles.includes('all')) {
        accessedRouters = allRoutes;
      } else {
        // 普通角色 - 进行路由过滤
        const res = filterPermissionsRouters(allRoutes, roles);
        accessedRouters = res.accessedRouters;
        removeRoutes = res.removeRoutes;
      }

      // 更新store状态
      this.routers = accessedRouters;
      this.removeRoutes = removeRoutes;

      // 从路由实例中移除无权限的路由
      removeRoutes.forEach((item: RouteRecordRaw) => {
        if (router.hasRoute(item.name)) {
          router.removeRoute(item.name); // 移除路由
        }
      });
    },

    /**
     * 恢复被移除的路由（用于权限变更时）
     */
    async restore() {
      // 将所有被移除的路由重新添加到路由实例
      this.removeRoutes.forEach((item: RouteRecordRaw) => {
        router.addRoute(item);
      });
    },
  },
});

/**
 * 获取权限store实例
 * @returns 权限store实例
 */
export function getPermissionStore() {
  return usePermissionStore(store);
}
